home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d18 / futils.arc / XWIN.DOC < prev    next >
Text File  |  1991-04-28  |  13KB  |  337 lines

  1.  
  2. ********************************************************************
  3. ************************* XWIN by Rex Kerr *************************
  4. ************************ Copyright (C) 1989 ************************
  5. ********************************************************************
  6.  
  7. This is a unit designed to give simple windowing capabilities to
  8. any program.  It uses FWRITE, so it is very fast, but it also
  9. causes snow on snowy CGAs.  It also won't autodetect EGA or VGA
  10. cards (another weakness of FWRITE).  It should work with EGA or
  11. VGA normally, but not with the large screen sizes. But it is very
  12. fast, and it works well for most programs that need windowing.
  13.  
  14. XWIN is implemented using a circular doubly linked list.  Therefore,
  15. you can call up any window at any time.  By the way, it uses the
  16. standard DOS and CRT units as well as my FWRITE unit.
  17.  
  18. ***
  19.  
  20. XWIN's window structure is declared like this:
  21.  
  22. type win_scrbuf = array[1..4000] of byte;  { This stores the window }
  23.      winptr = ^winrec;
  24.      winrec = record
  25.                     x,y,w,h : byte;    { The borders of the window }
  26.                     cx,cy : byte;     { The position of the cursor }
  27.                     id : byte;        { Each window has a unique ID
  28.                                         number }
  29.                     scrsize : word;   { The memory taken by the window
  30.                                         buffer, in bytes }
  31.                     wscreen : win_scrbuf;  { This is where the
  32.                                               saved window goes }
  33.                     up,dn : winptr; { Pointers to the windows after
  34.                                       and before this one }
  35.                     setas : byte;   { If bit 0 is on, there is a
  36.                                       border.  If bit 1 is on, the
  37.                                       window is hidden. }
  38.               end;
  39.  
  40. The only visible variable in the XWIN unit is the "base" of the
  41. window list.  The current window is always one up from this.
  42.  
  43. var windowset : winptr;
  44.  
  45. ***
  46.  
  47. GetWinVram(var Scrn : Win_ScrBuf; x,y,w,h : byte);
  48.  
  49. This takes care of saving the window.  Scrn is assumed to be
  50. exactly the same size as it takes to hold the window defined
  51. in x,y,w,h.  Since the other windowing routines call it themselves,
  52. you will probably not need to use this.
  53.  
  54. ***
  55.  
  56. PutWinVram(Scrn : Win_ScrBuf);
  57.  
  58. This puts the window back on the screen after it has been saved.
  59. Once again, Scrn is assumed to be just the right size.
  60.  
  61. ***
  62.  
  63. Bordermaker(a,b,c,d,e,f : byte) : string;
  64.  
  65. This turns bytes a,b,c,d,e,f into characters and places them in a
  66. string.  It is useful for making window borders with ASCII values
  67. above 126 or below 32.
  68.  
  69.     border1 := bordermaker(218,191,192,217,196,179);
  70.        { Window with a single-line border }
  71.  
  72.     border2 := bordermaker(201,187,200,188,205,186);
  73.        { Window with a double-line border }
  74.  
  75.  
  76.  
  77. ***
  78.  
  79. SetTextAttr(attr : byte);
  80.  
  81. This sets the current writing attribute for Turbo Pascal's Write
  82. and WriteLn.
  83.  
  84. ***
  85.  
  86. GetXY(var x,y : byte);
  87.  
  88. This calls TP5's WhereX and WhereY.  It's just a time-saver.
  89. Note: If you are using FBIOS, BiosGetXY is much faster.
  90.  
  91. ***
  92.  
  93. CreateWindow(id : byte; x,y,w,h : byte; wattr,battr : byte;
  94.              st,border : string);
  95.  
  96. Wow!  What does this do?
  97.  
  98. The borders of the window are x,y,w,h.  Border is either an empty
  99. string (for no border) or the 6 chars used in the border.  This is
  100. what the characters are used for:
  101.       #1 : top left corner         #2: top right corner
  102.       #3 : bottom left corner      #4: bottom right corner
  103.       #5 : horizontal lines        #6: vertical lines
  104.  
  105. St is the string used for the "title" of the window.  It is placed
  106. centered in the top line of the border.  If there is no border, st
  107. is not used.  Batr is the attribute used for the border, and Watr
  108. is the attribute used for the main text.  While we're at it, here's
  109. a table showing the which values give which colors:
  110.  
  111. COLOR         FOREGROUND    BACKGROUND   HI-INTENSITY FOREGROUND
  112. Black             0             0             8  (Gray)
  113. Blue              1             16            9  (Light blue)
  114. Green             2             32            10 (Light green)
  115. Cyan              3             48            11 (Light cyan)
  116. Red               4             64            12 (Pink)
  117. Magenta           5             80            13 (Light magenta)
  118. Brown             6             96            14 (Yellow)
  119. White             7             112           15 (Hi-intensity white)
  120.  
  121. To get the desire attribute, add the foreground color to the
  122. background color.  For example, to get white on a black background,
  123. the attribute is 7.  For pink on a magenta background, the
  124. attribute is 92.  To make the foreground characters blink, add 128
  125. to the total.
  126.  
  127. And finally, ID is the window's unique identification number.  You
  128. use it in most of the other window routines.  If you specify the ID
  129. number of an already existing window, nothing will happen.
  130.  
  131. ***
  132.  
  133. PutWinBorder(x,y,w,h : byte; St,Border : string; Batr : byte);
  134.  
  135. This just writes a window border to the screen without actually
  136. creating a window.  You can use it to change the border of the
  137. current window (by overwriting the old one) or just to write a
  138. window box to the screen.  The inside of the box is not cleared.
  139. Border is a string of the border characters as shown in
  140. CreateWindow, and St is the string to write in the border.  Batr
  141. is the attribute to use.
  142.  
  143. ***
  144.  
  145. FancyWinBorder(x,y,w,h:byte; St,St2,Border:string; Batr,Ttatr,Btatr:byte);
  146.  
  147. Sometimes you want a fancier border than CreateWindow will give you.
  148. The window's border is not saved as the six border chars and the
  149. string to write.  Instead, it is just saved as it in shown on the
  150. screen.  So if you somehow get "bad" characters in the border,
  151. they'll stay there.  But you can also use it to overwrite the old
  152. border with a new one.
  153.  
  154. x,y,w,h is the border of the window (the same as CreateWindow)
  155. St is the string to write in the top line of the border
  156. St2 is the string to write in the bottom line of the border
  157. Ttatr is the attribute to use for St
  158. Btatr is the attribute to use for St2
  159. Batr is the attribute to use for the rest of the border.
  160. Border is similar to but different from the one in CreateWindow.
  161. This is what FancyWinBorder's characters are used for:
  162.    #1 : Top right corner         #2 : Top left corner
  163.    #3 : Bottom right corner      #4 : Bottom left corner
  164.    #5 : Top right horizontal     #6 : Top left horizontal
  165.    #7 : Bottom right horizontal  #8 : Bottom left horizontal
  166.    #9 : Top right vertical       #10 : Top left vertical
  167.    #11 : Bottom right vertical   #12 : Bottom left vertical
  168. So you have greater control over what the border looks like.
  169.  
  170. If you call FancyWinBorder(1,1,10,6,'','','abcdefghijkl',7,7,7)
  171. you will get:
  172.  
  173. aeeeeffffb
  174. i        j
  175. i        j
  176. k        l
  177. k        l
  178. cgggghhhhd
  179.  
  180.  
  181. ***
  182.  
  183. UpdateWindows;
  184.  
  185. This updates the screen.  You use it after you have called a
  186. procedure or function that changes or removes the window, but
  187. doesn't update the screen.
  188.  
  189. ***
  190.  
  191. SaveWindow;
  192.  
  193. This saves the current window on the screen to memory.  If you
  194. have written to the top window since you got to it, you need to
  195. call this before calling UpdateWindow.  If you don't, the changes
  196. will be erased.  You do not need to call this before any other
  197. procedures.
  198.  
  199. ***
  200.  
  201. RemoveWindow(id : byte);
  202.  
  203. This removes the window (specified by ID) from the linked list.  It
  204. doesn't, however, do anything about the image on the screen.  If you
  205. specify an ID that is non-existant, nothing will happen.  You can
  206. check to see if a window exists or not using ExistWindow.  You will
  207. probably want to call UpdateScreen soon after you call this.
  208.  
  209. ***
  210.  
  211. GotoWindow(id : byte);
  212.  
  213. This gets the specified window and puts it at the beginning of the
  214. linked list and updates the screen.  If a non-existant ID is called,
  215. nothing will happen.
  216.  
  217. ***
  218.  
  219. HideWindow(id : byte);
  220.  
  221. This sets the window to be hidden.  It doesn't do anything about the
  222. screen, so UpdateScreen has to be called for that.  If you use
  223. gotowindow to go to the hidden window, the window will unhide.  Also,
  224. if you use popwindow and end up at a hidden window, the window will
  225. unhide itself.
  226.  
  227. ***
  228.  
  229. PopWindow;
  230.  
  231. This removes the current window from the linked list and the screen.
  232. The window behind the current window now becomes the current window.
  233.  
  234. ***
  235.  
  236. PopManyWindows(num : byte);
  237.  
  238. If you want to pop more than one window, use this.  It is much
  239. faster than PopWindow for popping more than one window.
  240.  
  241. ***
  242.  
  243. ExistWindow(id : byte) : boolean;
  244.  
  245. This returns true if a window with the specified ID exists.
  246. Otherwise, it returns false.
  247.  
  248. ***
  249.  
  250. Okay, that's everything.  But I'd like to write one extra routine
  251. here.  With createwindow, one of the problems is that it's a bit
  252. hard to find out which ID numbers are already existing.  You could
  253. call existwindow from 1 until you get a false, but if you have a lot
  254. of windows, that could take a few extra lines of code and extra time
  255. that you might not want wasted. So let's write a function that returns
  256. the lowest unused ID.
  257.  
  258. function EmptyWindowID : byte;
  259. var temptr : winptr;   { We need a pointer to walk through the list }
  260.     i,j : byte;      { Variables for storing the free ID }
  261. begin
  262.      i := 0; j := 0;    { Initialize the variables }
  263.      while (i <> 0) do    { i gets set to the free ID #.  It will }
  264.      begin                { remain 0 until then. }
  265.           inc(j);    { j is the counter for possible open windows }
  266.           temptr := windowset^.up;  { temptr is pointing to the
  267.                                       current window }
  268.           while (temptr <> windowset) and (temptr^.id <> j) do
  269.           begin   { If temptr's ID = j or temptr has cirled the list, STOP }
  270.                nptr := nptr^.up;    { Go up to the next window }
  271.           end;
  272.           if nptr = windowset then i := j; { If temptr has circled, }
  273.      end;                 { that ID is free, so set i }
  274.      EmptyWindowID := i;  { give the function the result }
  275. end;
  276.  
  277.    What this does is it circles through the linked list to see if
  278. any of the windows have an ID of 1.  If none do, i is set to one.
  279. Otherwise, the same thing is done for 2 and 3 and 4 etc. until
  280. a "free" ID is found.  Then the function is set to the value of i
  281. (the free ID number).
  282.  
  283. A XWIN window takes up  22 bytes of heap plus the amount of memory
  284. required to save the window in memory.  Here's a formula to calculate
  285. that amount of memory:
  286.  
  287. mem_required := (window_width * window_height) * 2;
  288.  
  289. But you don't have to worry about calculating the memory; XWIN does
  290. it for you.  You may want to test the heap to make sure it has
  291. enough memory before calling createwindow.  Like this:
  292.  
  293. function enoughmemory(x,y,w,h : byte) : boolean;
  294. var temp : word;
  295. begin
  296.      temp := ((w - x) + 1) * ((h - y) + 1);
  297.      temp := (temp * 2) + 22;
  298.      if (maxavail >= temp) then enoughmemory := true
  299.      else enoughmemory := false;
  300. end;
  301.  
  302.  
  303.          ----------------end-of-author's-documentation---------------
  304.  
  305.                         Software Library Information:
  306.  
  307.                    This disk copy provided as a service of
  308.  
  309.                         The Public (Software) Library
  310.  
  311.          We are not the authors of this program, nor are we associated
  312.          with the author in any way other than as a distributor of the
  313.          program in accordance with the author's terms of distribution.
  314.  
  315.          Please direct shareware payments and specific questions about
  316.          this program to the author of the program, whose name appears
  317.          elsewhere in  this documentation. If you have trouble getting
  318.          in touch with the author,  we will do whatever we can to help
  319.          you with your questions. All programs have been tested and do
  320.          run.  To report problems,  please use the form that is in the
  321.          file PROBLEM.DOC on many of our disks or in other written for-
  322.          mat with screen printouts, if possible.  The P(s)L cannot de-
  323.          bug programs over the telephone.
  324.  
  325.          Disks in the P(s)L are updated monthly, so if you did not get
  326.          this disk  directly from the P(s)L,  you should be aware that
  327.          the files in this set may no  longer be the current versions.
  328.  
  329.          For a copy of the latest monthly software library newsletter
  330.          and a list of the 2,000+ disks in the library, call or write
  331.  
  332.                         The Public (Software) Library
  333.                               P.O.Box 35705 - F
  334.                            Houston, TX 77235-5705
  335.                                (713) 665-7017
  336.  
  337.